<template>
  <div class="menu-list">
    <div class="menu-list-title">菜单/按钮权限</div>
    <div class="menu-list-body" v-loading="loading">
      <table class="menu-list-table">
        <tr v-if="menus.length" key="first">
          <td class="menu-list-td">
            <ElCheckbox
              :checked="value.has(10000)"
              @change="onChange(10000)"
            >工作台</ElCheckbox>
          </td>
          <td></td>
          <td></td>
        </tr>
        <template v-for="menu in menus" :key="menu.menuId">
          <tr v-for="(row, index) in menu.list || []" :key="row.menuId">
            <td v-if="!index" :rowspan="menu.list.length" class="menu-list-td" :class="{ 'is-first': !index }">
              <ElCheckbox
                :checked="value.has(menu.menuId)"
                @change="onChange(menu.menuId)"
              >{{ menu.name }}</ElCheckbox>
            </td>
            <td class="menu-list-td" :class="{ 'is-first': !index }">
              <ElCheckbox
                :checked="value.has(row.menuId)"
                :model-value="value.has(row.menuId)"
                @change="onChange(row.menuId)"
              >{{ row.name }}</ElCheckbox>
            </td>
            <td class="menu-list-td" :class="{ 'is-first': !index }">
              <div class="menu-list-perms">
                <ElCheckbox
                  v-for="perm in row.list || []"
                  :key="perm.menuId"
                  :checked="value.has(perm.menuId)"
                  :model-value="value.has(perm.menuId)"
                  @change="onChange(perm.menuId)"
                >{{ perm.name }}</ElCheckbox>
              </div>
            </td>
          </tr>
        </template>
      </table>
      <ElEmpty v-if="!menus.length" />
    </div>
  </div>
</template>

<script lang="ts">
import { ElLoadingDirective } from 'element-plus'
export default {
  directives: {
    loading: ElLoadingDirective
  }
}
</script>

<script setup lang="ts">
import { onMounted, ref, computed } from 'vue'
import { ElCheckbox, ElEmpty } from 'element-plus'
import { getMenusList } from '../api'

interface Props {
  modelValue: string[];
  data: object;
}
const props = withDefaults(defineProps<Props>(), {
  modelValue: () => [],
  data: () => ({})
})

interface Emits {
  'update:model-value': [string[]]
}
const emit = defineEmits<Readonly<Emits>>()

const value = computed(() => new Set(props.modelValue))

const loading = ref(false)
const menus = ref([])
// 只记录前两层数据
const menusMap = computed(() => {
  const map = new Map()
  menus.value.forEach(item => {
    map.set(item.menuId, item)
    if (item.list && item.list.length) {
      item.list.forEach(i => {
        map.set(i.menuId, i)
      })
    }
  })
  return map
})
onMounted(() => {
  loading.value = true
  getMenusList()
    .then(res => {
      console.log('数据来了');
      console.log(res);
      menus.value = res || []
    })
    .finally(() => {
      loading.value = false
    })
})

const onChange = (val) => {
  const v = new Set(props.modelValue)
  if (v.has(val)) {
    v.delete(val)
    const menu = menusMap.value.get(val)
    if (menu && menu.list && menu.list.length) {
      menu.list.forEach(item => {
        v.delete(item.menuId)
        if (item.list && item.list.length) {
          item.list.forEach(i => {
            v.delete(i.menuId)
          })
        }
      })
    }
  } else {
    v.add(val)
    const menu = menusMap.value.get(val)
    if (menu && menu.list && menu.list.length) {
      menu.list.forEach(item => {
        v.add(item.menuId)
        if (item.list && item.list.length) {
          item.list.forEach(i => {
            v.add(i.menuId)
          })
        }
      })
    }
  }
  emit('update:model-value', [...v])
  
}
</script>

<style scoped lang="scss">
.menu-list {
  width: 100%;
  &-title {
    font-family: PingFangSC-Medium;
    font-weight: 500;
    font-size: 13px;
    color: #333333;
  }

  &-table {
    white-space: nowrap;
    border-collapse: collapse;
    border: 1px solid #DFDFDF;
  }
  &-td {
    vertical-align: top;
    border-right: 1px solid #DFDFDF;
    padding: 4px 9px;
    &.is-first {
      border-top: 1px solid #DFDFDF;
    }
  }
  &-perms {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
  }
}
</style>
